<!DOCTYPE html>
<html>

  <head>
	<meta charset="UTF-8">
	<title>Xtext - Xtext 2.35.0 Release Notes</title>
	
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description"
		content="The website of Eclipse Xtext, an open-source framework for development of programming languages and domain-specific languages">
	<meta name="author" content="Sven Efftinge">
	<meta name="author" content="Miro Spoenemann">
	<!--  styles -->
	<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
	<!--[if lt IE 9]>
	  <script src="https://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	
	<!-- Le fav and touch icons -->
	<link rel="shortcut icon" href="/Xtext/images/favicon.png">
	
	<link href="/Xtext/css/bootstrap.css" rel="stylesheet" type='text/css'>
	<link href="/Xtext/css/bootstrap-responsive.css" rel="stylesheet" type='text/css'>
	<link href="/Xtext/css/shield-responsive.css" rel="stylesheet" type='text/css'>
	<link href='/Xtext/css/fonts.css' rel='stylesheet' type='text/css'>
	<link href="/Xtext/css/prettyPhoto.css" rel="stylesheet" media="screen" type='text/css'>
	<link href="/Xtext/css/prettify.css" type="text/css" rel="stylesheet"/>
	<link href="/Xtext/css/style.css" rel="stylesheet" type='text/css'>
	<!-- cover flow -->
	<link href="/Xtext/css/coverflow.css" rel="stylesheet" type='text/css'>
	<!--[if lt IE 9]>
	  <link href="/css/iebugs.css" rel="stylesheet" type='text/css'>
	<![endif]-->

	<!-- BEGIN Cookie Consent
	<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.css" />
	<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.js"></script>
	<script>
	window.addEventListener("load", function(){
	window.cookieconsent.initialise({
		"palette": {
		"popup": {
		  "background": "#000"
		},
		"button": {
		  "background": "#f1d600"
		}
		},
		"theme": "edgeless",
		"type": "opt-in",
		onInitialise: function (status) {
		  var type = this.options.type;
		  var didConsent = this.hasConsented();
		  if (type == 'opt-in' && didConsent) {
		    // TODO: enable cookies
		  }
		  if (type == 'opt-out' && !didConsent) {
		    // TODO: disable cookies
		  }
		},
		onStatusChange: function(status, chosenBefore) {
		  var type = this.options.type;
		  var didConsent = this.hasConsented();
		  if (type == 'opt-in' && didConsent) {
		    // TODO: enable cookies
		  }
		  if (type == 'opt-out' && !didConsent) {
		    // TODO: disable cookies
		  }
		}, 
		onRevokeChoice: function() {
		  var type = this.options.type;
		  if (type == 'opt-in') {
		    // TODO: disable cookies
		  }
		  if (type == 'opt-out') {
		    // TODO: enable cookies
		  }
		},
		"content": {
		"href": "https://www.eclipse.org/legal/privacy.php"
		}
	})});
	</script>
	END Cookie Consent -->
</head>


  <body>
  
    <header class="site-header">

  <!-- Navbar -->
  <div class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <a class="btn btn-navbar" data-toggle="collapse"
          data-target=".nav-collapse"> <span class="icon-bar"></span> <span
          class="icon-bar"></span> <span class="icon-bar"></span>
        </a> <a class="brand" href="/Xtext/index.html"></a>
        <div class="nav-collapse collapse" style="height: 0px;">
          <ul class="nav">
            <!--li ><a href="/Xtext/news.html">News</a></li-->
            <li ><a href="/Xtext/download.html">Download</a></li>
            <li ><a href="/Xtext/documentation/index.html">Documentation</a></li>
            <li ><a href="/Xtext/community.html">Community</a></li>
            <li class="dropdown">
              <a class="dropdown-toggle" data-toggle="dropdown" href="#">Support &amp; Trainings<span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="https://info.itemis.com/professional-xtext-support" target="_blank">itemis</a></li>
                <li><a href="https://www.typefox.io/language-engineering/" target="_blank">TypeFox</a></li>
              </ul>
            </li>
            <li ><a href="https://eclipse.dev/Xtext/xtend">Xtend</a></li>
          </ul>
          <!--div class="nav pull-right">
            <li ><a><iframe src="https://ghbtns.com/github-btn.html?user=eclipse&repo=xtext&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></a></li>
          </div-->
        </div>
        <!--/.nav-collapse -->
      </div>
    </div>
  </div>
  <!-- Navbar End -->

</header>


    <div class="page-content">
  <div class="wrapper">
    <div id="page">  
    	<div class="inner">
    		<br/><br/>
    		<div id="maincontainer" class="container">
    			<div class="span8 offset1">
    				<h1>Xtext 2.35.0 Release Notes</h1>
    				<h4>May 28, 2024</h4>
    				<br/>
    				<p>Xtext 2.35.0 …</p>

<h2 id="call-to-action-secure-the-future-maintenance-of-xtext">Call to Action: Secure the future maintenance of Xtext</h2>

<p>As you might have recognized, the number of people contributing to Xtext on a regular basis has declined over the past years and so has the number of contributions. At the same time the amount of work for basic maintenance has stayed the same or even increased with the new release cadence of Java and the Eclipse simultaneous release. Briefly: The future maintenance of Xtext is at risk, at least in the current form and as part of the Eclipse Simrel. If you care, please join the discussion in <a href="https://github.com/eclipse-xtext/xtext/issues/1721">https://github.com/eclipse-xtext/xtext/issues/1721</a>.</p>

<h2 id="relevant-changes">Relevant changes</h2>

<h3 id="initial-support-for-java-21">Initial support for Java 21</h3>

<p>IMPORTANT: before switching to Java 21, make sure to go through the deprecation notice below about <code>org.eclipse.xtext.xbase.lib.IterableExtensions.last(Iterable&lt;T&gt;)</code>.</p>

<p>In Eclipse, using a recent JDT version, Xbase languages, including Xtend, can access Java 21 generated byte-code and refer to Java records.</p>

<p>For Maven/Tycho builds, e.g., <code>xtext-maven-plugin</code> and <code>xtend-maven-plugin</code>, a new version of <code>jdt.core</code>, e.g., 3.37.0, must be forced (currently, in the BOM, we still use an older version of JDT).<br />
This can be achieved by passing the system property <code>-Djava-21</code> when running Maven (our BOM will automatically activate the new version of JDT).<br />
Alternatively, you can place the line <code>-Djava-21</code> in your <code>.mvn/maven.config</code> file in the root folder.</p>

<p>For Gradle, you need to force the dependency of the new version of <code>jdt.core</code>, e.g., 3.37.0.</p>

<h3 id="normalization-of-eols-in-xbase-multi-line-strings">Normalization of EOLs in Xbase multi-line strings</h3>

<p>In Xbase languages (including Xtend), multi-line strings (that is, strings that span several lines, NOT Xtend template expressions) are now normalized concerning end-of-line characters, following the same strategies of <a href="https://docs.oracle.com/en/java/javase/21/text-blocks/index.html#normalization-of-line-terminators">Normalization Of Line Terminators in Java Text Blocks</a>: Windows CR in the DSL textual sources will not be part of the string in the generated Java code, which will only contain Unix LF.<br />
This change leads to the same Java code generated in Windows and Unix-like systems (see issue https://github.com/eclipse-xtext/xtext/issues/2293).</p>

<p>This DSL string</p>

<pre><code class="language-xtend">var s = "a multi
line string"
</code></pre>

<p>Will always result in the following generated Java code in Windows, Linux, and macOS:</p>

<pre><code class="language-java">String s = "a multi\nline string";
</code></pre>

<p>While before, in Windows, it would have been:</p>

<pre><code class="language-java">String s = "a multi\r\nline string";
</code></pre>

<p>Note that the behavior for explicit escape sequences (<code>\\r</code>) will remain the same as before.</p>

<h3 id="automatic-validation-for-xbase-languages">Automatic validation for Xbase languages</h3>

<p>The new <code>JvmGenericTypeValidator</code> was introduced to automatically perform several Java-related checks in the hierarchy of the inferred <code>JvmGenericType</code>s of an Xbase language, with the corresponding error reporting.<br />
For example, cycles in a hierarchy, extension of a final class, proper extension of an abstract class (do you implement all the abstract methods or declare the inferred class as abstract?), proper method overriding, etc. It also performs duplicate elements checks, like duplicate parameter names, duplicate fields and duplicate methods (keeping the type-erasure into consideration when using types with arguments).</p>

<p>This mechanism assumes that you implement the <code>JvmModelInferrer</code> “correctly”.<br />
It only checks the first inferred <code>JvmGenericType</code> for the same DSL element (i.e., if for an element <code>Entity</code> you infer two <code>JvmGenericType</code>s, <code>t1</code> and <code>t2</code>, only the first one will be checked).<br />
Moreover, it only checks Jvm model elements with an associated source element.<br />
Concerning intended classes to extend and interfaces to extend/implement, it assumes the model inferrer uses the new <code>JvmTypesBuilder#setSuperClass(JvmDeclaredType, JvmTypeReference)</code> and <code>JvmTypesBuilder#addSuperInterface(JvmDeclaredType, JvmTypeReference)</code>, respectively.</p>

<p>Currently, this validator must be enabled explicitly through the <code>composedCheck</code> in the MWE2 file or the <code>@ComposedChecks</code> annotation in the validator, e.g., <code>@ComposedChecks(validators = JvmGenericTypeValidator.class)</code>.</p>

<p>The Domainmodel example now uses this validator.<br />
The Xtend validator has been refactored to also use this validator.</p>

<h3 id="maven-building">Maven building</h3>

<p>When using <code>xtext-maven-plugin</code> for Xbase languages, relative paths (instead of absolute paths) are now generated in the <code>._trace</code> files.</p>

<p>The configuration option <code>writeStorageResources</code> has been added to <code>xtext-maven-plugin</code> to write the semantic model, the resource description, and optionally the node model to a ResourceStorage (<code>.bin</code> files).<br />
See <a href="https://github.com/eclipse-xtext/xtext/tree/main/org.eclipse.xtext.maven.plugin/src/test/resources/it/generate/simple-lang-write-storage-resources">this integration test</a> for an example.</p>

<p>To single-source the configuration of a language that is built with Maven, the configuration options <code>writeClasspathConfiguration</code> and <code>classpathConfigurationLocation</code> were added to the <code>xtext-maven-plugin</code>. If enabled, a property file will be written that contains the classpath information, model directories, output directories and lookup paths that were used for the plugin execution. The properties file contains file hashes that allow to track changed across subsequent runs.</p>

<h3 id="initial-lsp-support-for-xbase-languages">Initial LSP Support for Xbase Languages</h3>

<p>The initial support for language servers that use Xbase languages is part of this release. It’s based on binary Java resources and uses the classpath configuration that’s written by the maven plugin. Thereby, the Xtext language server can be configured such that Xbase language can resolve against class files from the current project. If a Java language server runs in parallel to the Xtext language server, and incrementally produces class files, the changes will be picked up by the Xtext language server.</p>

<h3 id="node-model-customizing">Node model customizing</h3>

<p>Low level APIs were added that allow to customizing the node model and the way it is stored on the EMF objects. This enables advanced use cases like unloading the node model for resources that are already fully resolved. The node model can be re-attached on demand for these cases. Curious users may want to configure the <code>DetachableNodeModelFragment</code> in their mwe2 workflows.</p>

<h3 id="initial-support-for-textmate-grammars">Initial Support for TextMate Grammars</h3>

<p>The highly configurable <code>DetachableNodeModelFragment</code> can be configured in the mwe2 workflow to emit textmate grammar to drive the lexical coloring in LSP clients that do have support for tm-language definitions.</p>

<h3 id="runtime-testing">Runtime Testing</h3>

<p>The <code>AbstractFormatterTest</code> base class has been added to the <code>org.eclipse.xtext.testing</code> package to provide a convenient way to test the formatter capabilities. The Xtext Domainmodel example project and the Xtend code base have been extended by concrete formatter test cases to demonstrate the usage of this framework class.</p>

<p>The generated <code>InjectorProvider</code> for runtime tests has been improved to make customizations easier w.r.t. OSGI/Maven environments (see <a href="https://github.com/eclipse-xtext/xtext/pull/3042">https://github.com/eclipse-xtext/xtext/pull/3042</a>).</p>

<p>The base class <code>AbstractXtextTests</code>, for “old”-style testing, is now part of <code>org.eclipse.xtext.testing</code>. (See also the removal notice below.)</p>

<p>Two new methods were added <code>org.eclipse.xtext.xbase.testing.CompilationTestHelper.Result.assertNoErrors()</code>/<code>assertNoIssues()</code> for checking whether during the compilation of the input sources errors, respectively, errors or warnings, were detected.</p>

<h3 id="ui-testing">UI Testing</h3>

<p>The <code>AbstractContentAssistTest</code> class has been extended by API methods to provide a convenient way to test proposals from several resources. The <code>StatemachineContentAssistTest</code> test class of the Xtext Statemachine example project demonstrates the usage of these new API methods.</p>

<h2 id="upgrades">Upgrades</h2>

<ul>
  <li>GSON is now on 2.11</li>
  <li>Guava was update to 33.2</li>
  <li>lsp4j is now on 0.23.x</li>
  <li>MWE(2) is now on 1.12/2.18</li>
</ul>

<h2 id="deprecations">Deprecations</h2>

<p>The method <code>org.eclipse.xtext.xbase.lib.IterableExtensions.last(Iterable&lt;T&gt;)</code> has been deprecated in favor of the new <code>org.eclipse.xtext.xbase.lib.IterableExtensions.lastOrNull(Iterable&lt;T&gt;)</code>.<br />
The reason is that Java 21 introduces the <code>getLast</code> method in a few collection classes.<br />
Xbase will prefer <code>getLast</code> to our extension method <code>last</code> to generate Java code when the runtime is Java 21 and the <code>last</code> extension method is used in an Xbase DSL code, e.g., Xtend.<br />
The problem is that our extension method <code>last</code> returns null when the collection is empty, while the <code>getLast</code> method in Java 21 throws a <code>NoSuchElementException</code>, leading to different semantics.</p>

<p>We encourage everyone to pay attention to such deprecations and switch to the new <code>lastOrNull</code>, which retains the semantics of <code>last</code>, <strong>before</strong> switching to Java 21.<br />
To keep the consistency between <code>IterableExtensions</code> and <code>IteratorExtensions</code> we also deprecated <code>last</code> in the latter and introduced <code>lastOrNull</code> in <code>IteratorExtensions</code>.</p>

<h2 id="future-removals-notice">Future removals notice</h2>

<p>In the next release, 2.36.0, the long time deprecated <code>org.eclipse.xtext.junit4</code> and <code>org.eclipse.xtext.xbase.junit</code> will be removed.<br />
The projects <code>org.eclipse.xtext.testing</code>, <code>org.eclipse.xtext.ui.testing</code>, <code>org.eclipse.xtext.xbase.testing</code> and <code>org.eclipse.xtext.xbase.ui.testing</code> already provide replacements for the above deprecated projects.<br />
Note that the old base class <code>AbstractXtextTests</code> is now part of <code>org.eclipse.xtext.testing</code>.</p>

<h2 id="credits">Credits</h2>

<p>The Xtext project is thankful for the dedication of each committer and contributor. This release has been made possible by the following persons (in order of the number of contributed commits to this release).</p>

<ul>
  <li>Lorenzo Bettini</li>
  <li>Christian Dietrich</li>
  <li>Sebastian Zarnekow</li>
  <li>Hannes Wellmann</li>
  <li>Tamas Miklossy</li>
  <li>Ed Merks</li>
  <li>Rubén Porras Campo</li>
  <li>Didier Vojtisek</li>
  <li>Ehab Younes</li>
  <li>Florian Pirchner</li>
</ul>

<h2 id="fixed-issues">Fixed Issues</h2>

<p>As in every release cycle we were eagerly hunting down bugs, and reviewed and integrated plenty of contributions. For further details please refer to the following lists:</p>

<ul>
  <li>
    <p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=is%3Aissue+milestone%3ARelease_2.35+is%3Aclosed+repo%3Aeclipse%2Fxtext+repo%3Aeclipse%2Fxtext-core+repo%3Aeclipse%2Fxtext-lib+repo%3Aeclipse%2Fxtext-extras+repo%3Aeclipse%2Fxtext-eclipse+repo%3Aeclipse%2Fxtext-idea+repo%3Aeclipse%2Fxtext-web+repo%3Aeclipse%2Fxtext-maven+repo%3Aeclipse%2Fxtext-xtend&amp;type=Issues&amp;ref=searchresults">Fixed GitHub issues</a></p>
  </li>
  <li>
    <p><a href="https://github.com/search?utf8=%E2%9C%93&amp;q=is%3Apr+milestone%3ARelease_2.35+is%3Aclosed+repo%3Aeclipse%2Fxtext+repo%3Aeclipse%2Fxtext-core+repo%3Aeclipse%2Fxtext-lib+repo%3Aeclipse%2Fxtext-extras+repo%3Aeclipse%2Fxtext-eclipse+repo%3Aeclipse%2Fxtext-idea+repo%3Aeclipse%2Fxtext-web+repo%3Aeclipse%2Fxtext-maven+repo%3Aeclipse%2Fxtext-xtend&amp;type=Issues&amp;ref=searchresults">Closed Pull Requests</a></p>
  </li>
  <li>
    <p><a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&amp;bug_status=VERIFIED&amp;bug_status=CLOSED&amp;classification=Modeling&amp;classification=Tools&amp;columnlist=product%2Ccomponent%2Cassigned_to%2Cbug_status%2Cresolution%2Cshort_desc%2Cchangeddate%2Ckeywords&amp;f0=OP&amp;f1=OP&amp;f3=CP&amp;f4=CP&amp;known_name=Xtext%202.31&amp;list_id=16618269&amp;product=TMF&amp;product=Xtend&amp;query_based_on=Xtext%202.31&amp;query_format=advanced&amp;status_whiteboard=v2.35&amp;status_whiteboard_type=allwordssubstr">Fixed Eclipse Bugzilla tickets</a></p>
  </li>
</ul>

    			</div>
    		</div>
      </div>
    </div>
  </div>
</div>
    
    <footer class="site-footer">
  <div id="extra">
    <div class="inner">
      <div class="container">
        <div class="row">
          <div class="span6">
            <h3 class="footer-links-header">Quick Links</h3>
            <ul class="footer-links clearfix">
              <li><a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
              <li><a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
              <li><a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
              <li><a href="https://www.eclipse.org/legal/">Legal</a></li>
            </ul>
            <ul class="footer-links clearfix">
              <li><a href="https://www.eclipse.org">Eclipse Home</a></li>
              <li><a href="https://marketplace.eclipse.org/">Market Place</a></li>
              <li><a href="https://www.planeteclipse.org/">Eclipse Planet</a></li>
              <li><a href="https://www.eclipse.org/forums/index.php/f/27/">Xtext Forum</a></li>
            </ul>
            <br/><br/>
            Xtext is a trademark of the Eclipse Foundation, Inc. and is used with permission
            <br/><br/>
            <img src="/Xtext/images/eclipse-foundation-white-orange.svg" alt="Eclipse Foundation"/>
          </div>
          <div class="span6">
            <!-- Social Media Links -->
            <h3 class="footer-links-header">Social Media</h3>
            <ul class="footer-links clearfix">
              <li>
                <a href="https://twitter.com/xtext"><img src="/Xtext/images/Twitter-bird-darkgray.png" class="img-responsive" style="margin-right: 5px;height: 1em;" alt="Twitter icon">@xtext on Twitter</a>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
  <a href="#" class="scrollup fadeOutRight animated" style="display: none;">ScrollUp</a>
  <!-- Le javascript
      ================================================== -->
  <!-- Placed at the end of the document so the pages load faster -->
  
  <script src="/Xtext/js/jquery-1.11.3.min.js"></script>
  <script src="/Xtext/js/bootstrap.min.js"></script>
  <script src="/Xtext/js/jquery.easing.1.3.js" type="text/javascript"></script>
  <script src="/Xtext/js/jquery.prettyPhoto.js" type="text/javascript"></script>
  <script src="/Xtext/js/prettify.js" type="text/javascript"></script>
  <script src="/Xtext/js/lang-xtend.js" type="text/javascript"></script>
  <script src="/Xtext/js/lang-common.js" type="text/javascript"></script>
  <script src="/Xtext/js/custom.js" type="text/javascript"></script>
  <!--script src="https://apis.google.com/js/platform.js" async defer></script-->
  <!--script type="text/javascript">
    var _gaq = _gaq || [];  
      _gaq.push([ '_setAccount', 'UA-2429174-3' ]);
    _gaq.push([ '_trackPageview' ]);
    (function() {
      var ga = document.createElement('script');
      ga.type = 'text/javascript';
      ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl'
          : 'https://www')
          + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga, s);
    })();
  </script-->
  <script src="/Xtext/js/coverflow.min.js" type="text/javascript"></script>
  <script>
      $(function() {
        $('#coverflow').coverflow({
          active : 1,
          visibleAside: 2,
          overlap : 0.5,
          scale : 0.9,
          angle : 20,
          trigger : {
            "itemfocus" : true,
            "swipe" : true,
            "mousewheel" : false
          }
        });
        $('#coverflow :hidden').toggle();
        $(window).resize(function() {
          $('#coverflow').coverflow();
        });
      });

  </script>
</footer>


  </body>

</html>
